# -*- mode: conf[space] -*-
#
#  Configuration file for ferm(1).
#

# I2P rules that grant access to the "i2psvc" user (those with $use_i2p) will
# only be enabled if the string "i2p" is entered at the boot prompt.
# Deny or reject rules affecting "i2psvc" will always be set.
def $use_i2p = `test -d /usr/share/i2p && echo 1 || echo 0`;

# IPv4
domain ip {
    table filter {
        chain INPUT {
            policy DROP;

            # Established incoming connections are accepted.
            mod state state (ESTABLISHED) ACCEPT;

            # Traffic on the loopback interface is accepted.
            interface lo ACCEPT;
        }

        chain OUTPUT {
            policy DROP;

            # Established outgoing connections are accepted.
            mod state state (ESTABLISHED) ACCEPT;

            # White-list access to local resources
            outerface lo {
                # Related outgoing ICMP packets are accepted.
                mod state state (RELATED) proto icmp ACCEPT;

                # White-list access to Tor's SOCKSPort's
                daddr 127.0.0.1 proto tcp syn dport 9050 {
                    mod owner uid-owner root ACCEPT;
                    mod owner uid-owner proxy ACCEPT;
                    mod owner uid-owner nobody ACCEPT;
                }
                daddr 127.0.0.1 proto tcp syn mod multiport destination-ports (9050 9061 9062 9150) {
                    mod owner uid-owner amnesia ACCEPT;
                }
                daddr 127.0.0.1 proto tcp syn dport 9062 {
                    mod owner uid-owner htp ACCEPT;
                    mod owner uid-owner tails-iuk-get-target-file ACCEPT;
                    mod owner uid-owner tails-upgrade-frontend ACCEPT;
                }

                # White-list access to Tor's ControlPort
                daddr 127.0.0.1 proto tcp dport 9051 {
                    mod owner uid-owner tor-launcher ACCEPT;
                    # Needed by a workaround in tordate (NM's 20-time.sh hook)
                    # for temporarily changing Tor's logging severity.
                    mod owner uid-owner root ACCEPT;
                }

                # White-list access to the Tor control port filter
                daddr 127.0.0.1 proto tcp dport 9052 {
                    mod owner uid-owner amnesia ACCEPT;
                }

                # White-list access to Tor's TransPort
                daddr 127.0.0.1 proto tcp dport 9040 {
                    mod owner uid-owner amnesia ACCEPT;
                }

                # White-list access to system DNS and Tor's DNSPort
                daddr 127.0.0.1 proto udp dport (53 5353) {
                    mod owner uid-owner amnesia ACCEPT;
                }

                # Whitelist access to Tor's DNSPort so I2P can resolve hostnames when bootstrapping
                daddr 127.0.0.1 proto udp dport 5353 {
                    @if $use_i2p mod owner uid-owner i2psvc ACCEPT;
                }

                # White-list access to ttdnsd
                daddr 127.0.0.2 proto udp dport 53 {
                    mod owner uid-owner amnesia ACCEPT;
                }
                daddr 127.0.0.2 proto tcp syn dport 53 {
                    mod owner uid-owner amnesia ACCEPT;
                }

                # White-list access to the accessibility daemon
                daddr 127.0.0.1 proto tcp syn dport 4101 {
                    mod owner uid-owner amnesia ACCEPT;
                }

                # White-list access to I2P services for the amnesia user (IRC, SAM, POP3, SMTP, and Monotone)
                # For more information, see https://tails/boum.org/contribute/design/I2P and https://geti2p.net/ports
                daddr 127.0.0.1 proto tcp syn mod multiport destination-ports (6668 7656 7659 7660 8998) {
                    @if $use_i2p mod owner uid-owner amnesia ACCEPT;
                }

                # Whitelist access to I2P services for the i2psvc user,
                # otherwise mail and eepsite hosting won't work. The mail ports (7659 and 7660) are
                # accessed by the webmail app
                daddr 127.0.0.1 proto tcp syn mod multiport destination-ports (7658 7659 7660) {
                    @if $use_i2p mod owner uid-owner i2psvc ACCEPT;
                }

                # Whitelist access to the i2pbrowser user
                daddr 127.0.0.1 proto tcp syn mod multiport destination-ports (4444 7657 7658) {
                    @if $use_i2p mod owner uid-owner i2pbrowser ACCEPT;
                }

                # White-list access to the java wrapper's (used by I2P) control ports
                # (see: http://wrapper.tanukisoftware.com/doc/english/prop-port.html)
                # If, for example, port 31000 is in use, it'll try the next one in sequence.
                daddr 127.0.0.1 proto tcp sport (31000 31001 31002) dport (32000 32001 32002) {
                    @if $use_i2p mod owner uid-owner i2psvc ACCEPT;
                }

                # White-list access to CUPS
                daddr 127.0.0.1 proto tcp syn dport 631 {
                    mod owner uid-owner amnesia ACCEPT;
                }

                # White-list access to Monkeysphere
                daddr 127.0.0.1 proto tcp syn dport 6136 {
                    mod owner uid-owner amnesia ACCEPT;
                }
            }

            # clearnet is allowed to connect to any TCP port via the
            # external interfaces (but lo is blocked so it cannot interfere
            # with Tor etc) including DNS on the LAN. UDP DNS queries are
            # also allowed.
            outerface ! lo mod owner uid-owner clearnet {
                proto tcp ACCEPT;
                proto udp dport domain ACCEPT;
            }

            # Local network connections should not go through Tor but DNS shall be
            # rejected. I2P is explicitly blocked from communicating with the LAN.
            # (Note that we exclude the VirtualAddrNetwork used for .onion:s here.)
            daddr (10.0.0.0/8 172.16.0.0/12 192.168.0.0/16) @subchain "lan" {
                proto tcp dport domain REJECT;
                proto udp dport domain REJECT;
                mod owner uid-owner i2psvc REJECT;
                ACCEPT;
            }

            # Tor is allowed to do anything it wants to.
            mod owner uid-owner debian-tor {
                proto tcp syn mod state state (NEW) ACCEPT;
            }

            # i2p is allowed to do anything it wants to on the internet.
            outerface ! lo mod owner uid-owner i2psvc {
                @if $use_i2p proto (tcp udp) ACCEPT;
            }

            # Everything else is logged and dropped.
            LOG log-prefix "Dropped outbound packet: " log-level debug log-uid;
            REJECT reject-with icmp-port-unreachable;
        }

        chain FORWARD {
            policy DROP;
        }
    }

    table nat {
        chain PREROUTING {
            policy ACCEPT;
        }

        chain POSTROUTING {
            policy ACCEPT;
        }

        chain OUTPUT {
            policy ACCEPT;

            # .onion mapped addresses redirection to Tor.
            daddr 127.192.0.0/10 proto tcp REDIRECT to-ports 9040;

            # Redirect system DNS to Tor's DNSport
            daddr 127.0.0.1 proto udp dport 53 REDIRECT to-ports 5353;
        }
    }
}

# IPv6:
domain ip6 {
    table filter {
        chain INPUT {
            policy DROP;

            # White-list access to the accessibility daemon
            interface lo saddr ::1 daddr ::1 proto tcp {
                dport 4101 ACCEPT;
                sport 4101 mod state state (ESTABLISHED) ACCEPT;
            }

        }

        chain FORWARD {
            policy DROP;
        }

        chain OUTPUT {
            policy DROP;

            # White-list access to the accessibility daemon
            outerface lo saddr ::1 daddr ::1 proto tcp {
                dport 4101 mod owner uid-owner amnesia ACCEPT;
                sport 4101 mod state state (ESTABLISHED) ACCEPT;
            }

            # Everything else is logged and dropped.
            LOG log-prefix "Dropped outbound packet: " log-level debug log-uid;
            REJECT reject-with icmp6-port-unreachable;
        }
    }
}
